<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>3_react生命周期(新)</title>
  </head>
  <body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/17.0.1/react.development.js"></script>
    <!-- 引入react-dom, 用于支持react操作DOM -->
    <script
      type="text/javascript"
      src="../js/17.0.1/react-dom.development.js"
    ></script>
    <!-- 引入babel, 用于将jsx转为js -->
    <script type="text/javascript" src="../js/17.0.1/babel.min.js"></script>

    <script type="text/babel">
    /*
        1. 初始化阶段： 由ReactDOM.render()触发---初次渲染
            1. constructor()
            2. componentWillMount()
            3. render()
            4. componentDidMount() ==> 常用
                    一般这这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息
        2. 更新阶段：由组件内部this.setState()或父组件render触发
            1. shouldComponentUpdate()
            2. componentWillUpdate()
            3. render() ==> 必须使用的一个
            4. componentDidUpdate()
        3. 卸载组件：由ReactDOM.unmountComponentAtNode()触发
            1. componentWillUnmount() ==> 常用
                    一般这这个钩子中做一些收尾的事，例如：关闭定时器、取消订阅消息
    */
      //创建组件
      class Count extends React.Component{

        constructor(props){
            super(props)
            console.log('Count --- constructor')
            //初始化状态
            this.state = {count:0}
        }
        
        //加1按钮的回调
        addOne = ()=>{
            //获取原状态
            const {count} = this.state
            //更新状态
            this.setState({count:count+1})
        }

        //若state的值在任何时候都取决于props，那么可以使用getDerivedStateFromProps
        static getDerivedStateFromProps(props,state){
            console.log('---getDerivedStateFromProps',props,state)
            return props
        }

        //在更新之前获取快照
        getSnapshotBeforeUpdate(){
            console.log("---getSnapeshotBeforeUpdate")
            return 'atguigu';
        }

        render(){
            console.log('Count --- render')
            return (
                <div>
                    <h1>数值为：{this.state.count}</h1>    
                    <button onClick={this.addOne}>点我+1</button>
                    <button onClick={this.death}>卸载组件</button>
                    <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>
                </div>
            )
        }

        death = ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            console.log('Count --- death')
        }

        force = ()=>{
            this.forceUpdate();
        }

        //组件挂在完毕的钩子
        componentDidMount(){
            console.log('Count --- componentDidMount')
        }

        //控制组件更新的“阀门”
        shouldComponentUpdate(){
            console.log('Count --- shoudComponentUpdate')
            return true
        }

        //组件更新完毕的钩子
        componentDidUpdate(preProps,preState,snapshotValue){
            console.log('Count --- componentDidUpdate',preProps,preState,snapshotValue)
        }

        //组件将要卸载的钩子
        componentWillUnmount(){
            console.log('Count --- componentWillUnmount')
        }

      }

      ReactDOM.render(<Count name="Tyler"/>, document.getElementById('test'))
    </script>
  </body>
</html>
